
TestDeviceManager{
    test_flow(){
        .....
    }
    test_register_hard_dev(){
        DeviceManager = new DeviceManager();
        assert(DeviceManager.register_hard_dev());
        assert(DeviceManager.get_dev_cb());
    }
    test_class_exception(){

    }
}


DeviceManager{
// Sigleton
    enum Type {
        HARD_DEV,
        SOFT_DEV,
    };

    //dev_manager 
    //static cb_dev_t * dev_cb_[2] =  {0};
    //static cb_dev_t * dev_cb_ctx[2] =  {0};
    register_hard_dev(cb){
        return 0;
        //dev_cb[SOFT_DEV] = create_hardClientDevice(cb);
    }
    unregister(SOFT_DEV, cb){
        dev....
    }
    get_dev_cb(DevType type){
        return 0;
    }
    get_dev_cb_ctx(Type type);
}

struct Device{
    struct {
        cb_f1;
        cb_f2;
        cb_f3;
        cb_f4;
        cb_f5;
    }cb_;
    is_init;
}

static create_clientDevice(cb){
   Device * ret = new Device();
   ret.cb = cb;
   ret.is_init = 0;
   return ret;
}

struct Device * create_hardClientDevice(cb){
    Device * ret = createClientDevice(cb);
    ret->private = 100;
    return  ret;
}
struct Device * create_softClientDevice(){
    Device * ret = createClientDevice(cb);
    ret -> private == 1000;
    return ret;
}

{
    is_inited = 0;
    type = 0;
    cb_dev_t * in_use_;

    int switchMode(dev_type){
        cur_in_use_ = manager.get_dev_cb(dev_type);
    }

    connect();
    disconnect();
    reset();
}
SoftClientDevice : Device{

}

ClientDevice{
    Device * curDev_;

    ClientDevice(){
    }

    void setState(Manager.Type type){
        curDev_ = Manager.get_dev_cb(type);
    }

     void init(){
         assert(type == 0 || type == 1);
         curDev_.connect();
     }
     void deinit(){
         assert(type == 0 || type == 1);
         curDev_->disconnect();
     }

     void reset(){
         curDev_->reset();
     }


     ~ClientDeviced(){
     }
}


client code : {
    DevManager.register_hard_dev( cb_dev_create(f1,f2), ctx);
    DevManager.register_soft_dev();

   ClientDevice * cliDevice =  new ClientDevice(Manager);
   cliDevice.setState(manager.Type.HARD_DEV);

    {
           cliDevice.init();
           ....
    }

   cliDevice.setState(manager.Type.Soft_DEV);


}

void free_clientDevice(ClientDevice * cliDevice){
    cliDevice.uninit();
    cliDevice.unregister_soft_dev();
    cliDevice.unregister_hard_dev();
}
ClientDevice * create_clientDeivce(){

    hard_dev = cb_dev_create( f1, f2 ,f3);
    ClientDevice cliDevice(hard_dev, hard_dev_ctx); 
    cliDevice.register_hard_dev(hard_dev, hard_dev_ctx);
    cliDevice.register_soft_dev();
    init();
    erturn cliDevice;
}
void client_all_ood_refactoring(){

    ClientDevice * cliDevice = create_clientDeivce();

    ClientSession cliSession(cliDevice);


    {
        ClientHello cliHello(&cliSession);
        Net.send(&cliHello)
    }
    
    {
        HelloRsp helloRsp(Net.recv());
        
        if(helloRsp.getDevType() != expectType){
            cliSession.modeSwitch(helloRsp.getDevType());
        }
        helloRsp.install(&cliSession);
        //cliSession->handleHello(&helloRsp);
    }

    {
        ClientAuth cliAuth(&cliSession);
        Net.send(&cliAuth);
    }
    
    {
        AuthRsp authRsp(Net.recv());
        authRsp.install(&cliSession);
        //cliSession->handleAuthRsp(&authRsp);
    }

    free:
        free_clientDevice(cliDevice);
}

void server_all_ood(){
    ServerDevice serDevice(ctx);
    Server server(serDevice);

    {
        ServerSession serSession(&server); //ServerSession create from server
        
        {
            ClientHello cliHello(Net.recv()); // create hello with NetRecv()->buffer
            HelloRsp helloRsp(serSession, &cliHello); // HelloRsp create from session & cliHello
            Net.send(helloRsp.toBuffer());
        }

        {
            ClientAuth cliAuth(Net.recv()); //create auth from buffer(net.recv)
            AuthRsp authRsp(serSession, &cliAuth); // create AuthRsp from session & cliAuth
            Net.send(authRsp.toBuffer());
        }
    }
}



void data_clumps(){

    str_t  *src = str_create_as_cstr("abc");
    str_t *dst = str_create_as_zero_array(1024);
    str_t *plaintext = str_create_as_zero_array(1024);

    sge_packet_encrypt(cli_session, &src, &dst, cli_ctx, &err_code));

    str_free(plaintext)


}
